import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class IIanModel
{
	public List<List<Integer>> Usertests = new ArrayList<List<Integer>>();
	public List<List<Integer>> Userdatas = new ArrayList<List<Integer>>();
	public List<List<Float>> Userdist = new ArrayList<List<Float>>();
	private int usernumbers = 5551;
	private int articlenumbers = 16980;
	public File youfile;
	public FileOutputStream fos;
	public String strW = "result.txt";
	private static OutputStreamWriter osw;
	private static int countasdf= 0;
	
	public IIanModel() {
		Userdatas = new ArrayList<List<Integer>>();
		Userdist = new ArrayList<List<Float>>();
	}
	
	public void GetDataModel(String Path)
	{
		try
		{
			File youfile = new File(strW);
		    FileOutputStream fos = new FileOutputStream(youfile);
		    osw = new OutputStreamWriter(fos);
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		
		File dataFile = new File(Path);
		try{
			BufferedReader br = new BufferedReader(new FileReader(dataFile));
	        String line = ""; 
	        int userid = 0;
	        int lastuserid = -1;
	        Userdatas.add(new ArrayList<Integer>());//使得下标从1开始
	        String[] infoStrings = null;
	        //取得5551个用户的喜欢，get(i)得到的是第i个用户的喜欢列表
	        while ((line = br.readLine()) != null) { 
	            infoStrings = line.split(",");
	            userid = Integer.valueOf(infoStrings[0]);
	            if(userid != lastuserid) {
	            	Userdatas.add(new ArrayList<Integer>());
	            	lastuserid = userid;
	            }
	            Userdatas.get(userid).add(Integer.valueOf(infoStrings[1]));
	        } 	
	        br.close();
	        
	        //计算不同用户之间的距离
	        //下标从1开始
	        Userdist.add(new ArrayList<Float>());
	        for(int i = 1; i <= usernumbers; i++)
	        {
	        	List<Float> tempList = new ArrayList<Float>();
	        	tempList.add((float) 0);
	        	//计算第i个用户和其他用户之间的距离
	        	for(int j = 1; j <= usernumbers; j++)
	        	{
	        		if(i == j) {tempList.add((float) 0);continue;}
	        		
	        		float d = CalcSimilarity(Userdatas.get(i), Userdatas.get(j));
					System.out.println(i + " " + j);
	        		tempList.add((float) d);
	        	}
	        	Userdist.add(tempList);
	        }	        
	        
		}
		catch(Exception e){
			e.printStackTrace();
		}
	}
	
	public void Loadtest()
	{
		try{
			BufferedReader br = new BufferedReader(new FileReader(new File("c://user-info-test.csv")));
	        String line = ""; 
	        int userid = 0;
	        int lastuserid = -1;
	        Usertests.add(new ArrayList<Integer>());//使得下标从1开始
	        String[] infoStrings = null;
	        //取得5551个用户的喜欢，get(i)得到的是第i个用户的喜欢列表
	        while ((line = br.readLine()) != null) { 
	            infoStrings = line.split(",");
	            userid = Integer.valueOf(infoStrings[0]);
	            if(userid != lastuserid) {
	            	Usertests.add(new ArrayList<Integer>());
	            	lastuserid = userid;
	            }
	            Usertests.get(userid).add(Integer.valueOf(infoStrings[1]));
	        } 	
	        br.close();
	    }
		catch(Exception e){
			e.printStackTrace();
		}
	}
	
	public float CalcSimilarity(List<Integer> User1, List<Integer> User2)
	{
		float count = 0;
		for(int i : User1)
		{
			if(User2.contains(i))  
			{
				count++;
			}
		}
		return (count / (User1.size() + User2.size()));
	}
	
	public List<Integer> Recommand(int userid, int recommandNumbers, List<Float> list)
	{
		Float [] scores = new Float[articlenumbers + 1];
		for(int k = 0; k <= articlenumbers; k++)
		{
			scores[k] =  (float) 0;
		}
		
		for(int i = 1; i <= usernumbers; i++)
		{
			if(i == userid) continue;
			List<Integer> userdts = Userdatas.get(i);
			Float reladist = list.get(i);
			for(int j : userdts) scores[j] += reladist;
		}
		
		Integer [] returnnubers = new Integer[50];
		for(int k = 0; k < 50; k++)
		{
			returnnubers[k] = 0;
		}
		
		for(int i = 1; i <= articlenumbers; i++)
		{
			int k = 0;
			if(scores[i] == 0) continue;
			else{
				while(scores[i] > scores[returnnubers[k]]){
					
					if(k != 0) returnnubers[k - 1] = returnnubers[k];
					returnnubers[k] = i;	
					k++;
					if(k == 50) break;
				}
			}
		}
		
		Float maxs = (float) 999999;
		int count = 0;
		
		try {
			osw.write(userid + ",");
		} catch (IOException e1) {
			e1.printStackTrace();
		}
		
		for(int k = 49; k >= 0; k--)
		{
			if(count == 5) break;
			//if(i == 5) break;
			//if(j >= Userdatas.size()) {System.out.println(r);i++;}
			//else if(Userdatas.get(j).contains(r.getItemID())) {
			if(Userdatas.get(userid).contains(returnnubers[k])) {
				try {
					if(count == 0) maxs = scores[returnnubers[k]];
					if(count < 4) osw.write(returnnubers[k] + ";");
					else if(count == 4)osw.write(returnnubers[k] + "\r\n");
					//osw.write((scores[returnnubers[k]]/maxs) + " ");
					count++;
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		try{
		//if(count == 0) {osw.write("1;3;4;5;6\r\n");countasdf++;}
		//else if(count == 1) {osw.write("1;2;4;5\r\n");countasdf++;}
		//else if(count == 2) {osw.write("2;3;4\r\n");countasdf++;}
		//else if(count == 3) {osw.write("3;4\r\n");countasdf++;}
		//else if(count == 4) {osw.write("4\r\n");}countasdf++;}
		if(count == 0) {osw.write("\r\n");countasdf++;}
		else if(count == 1) {osw.write("\r\n");countasdf++;}
		else if(count == 2) {osw.write("\r\n");countasdf++;}
		else if(count == 3) {osw.write("\r\n");countasdf++;}
		else if(count == 4) {osw.write("\r\n");}countasdf++;}
		catch(Exception e)
		{}

		return Arrays.asList(returnnubers);
	}
	
	public static void main(String args[]) throws Exception
	{	
		IIanModel i = new IIanModel();
		i.GetDataModel("c://user-info-train.csv");
		i.Loadtest();
		
		for(int j = 1; j <= 5551; j++)
		{
			System.out.println(j);
			List<Integer> lr = i.Recommand(j, 50, i.Userdist.get(j));
			System.out.println(lr);
		}
		System.out.println(countasdf);
		osw.close();
	}
}